//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<CDepthRenderTarget9.cpp>
///	@path	~/src/graphics/dx9/
///	@date	2008/09/20
///	@desc	.

#include "config/config.h"

#include "graphics/DxHelpers.h"
#include "graphics/dx9/CDepthRenderTarget9.h"
#include "graphics/dx9/CTexture2D9.h"

namespace xeres {

	IMPL_IOBJECT_CLASS( CDepthRenderTarget9 );
	
	// CDepthRenderTarget9
	CDepthRenderTarget9::CDepthRenderTarget9( IDirect3DSurface9 * depthStencil )
		: m_surface( depthStencil )
	{
		HRESULT hr = m_surface->GetDesc( &m_desc );
		XS_ASSERT( SUCCEEDED(hr) );
	}
	// ~CDepthRenderTarget9
	CDepthRenderTarget9::~CDepthRenderTarget9( void )
	{
		if( m_surface )
		{
			UINT rest = m_surface->Release();
			if( rest != 0 )
			{
				TRACE_ERROR( _S("CDepthRenderTarget9::DTOR: Invalid IDirect3DSurface9 reference count.") );
				FATAL_ABORT( _S("Invalid IDirect3DSurface9 reference count.") );
			}
		}
	}

	// OnLostDevice
	bool CDepthRenderTarget9::OnLostDevice( void )
	{
		if( m_surface )
		{
			UINT rest = m_surface->Release();
			if( rest != 0 )
			{
				TRACE_ERROR( _S("CDepthRenderTarget9::OnLostDevice: Invalid IDirect3DSurface9 reference count.") );
				FATAL_ABORT( _S("Invalid IDirect3DSurface9 reference count.") );
			}
		}
		return true;
	}

	// OnResetDevice
	bool CDepthRenderTarget9::OnResetDevice( RefWeak<IDevice> device )
	{
		RefWeak<CDevice9> d3d9 = device;
		HRESULT hr = d3d9->GetDevice()->CreateDepthStencilSurface(
			m_desc.Width , m_desc.Height , m_desc.Format , m_desc.MultiSampleType , m_desc.MultiSampleQuality , FALSE , &m_surface , NULL );
		if( FAILED(hr) )
		{
			TRACE_ERROR( _S("CColorRenderTarget9::OnResetDevice: Failed to re-create render target: %s") , d3d_get_err(hr) );
			return false;
		}
		return true;
	}

	// GetType
	TextureType CDepthRenderTarget9::GetType( void )
	{
		return TEXTURE_DEPTH;
	}

	// GetSize
	Pair<int> CDepthRenderTarget9::GetSize( void )
	{
		return Pair<int>( m_desc.Width , m_desc.Height );
	}

	// GetDepth
	size_t CDepthRenderTarget9::GetDepth( void )
	{
		FATAL_ABORT( _S("Try to get depth from 2D texture.") );
		return 0;
	}

	// Map
	bool CDepthRenderTarget9::Map( uint sub , ResourceMap& data )
	{
		return false;
	}

	// ReadBack
	bool CDepthRenderTarget9::ReadBack( uint sub , ResourceMap& data , bool readonly )
	{
		return false;
	}

	// Update
	bool CDepthRenderTarget9::Update( uint sub , const Box<uint>& size , const byte * data , uint row_pitch , uint depth_pitch )
	{
		return false;
	}

	// Unmap
	bool CDepthRenderTarget9::Unmap( uint sub )
	{
		return false;
	}

	// ApplyTarget
	bool CDepthRenderTarget9::ApplyTarget( RefWeak<IDevice> device )
	{
		XS_ASSERT( device->IsA<CDevice9>() );

		RefWeak<CDevice9> d3d9 = device;
		HRESULT hr = d3d9->GetDevice()->SetDepthStencilSurface( m_surface );
		if( FAILED(hr) )
		{
			TRACE_ERROR( _S("CColorRenderTarget9::Apply: Failed to set render target: %s.") , d3d_get_err(hr) );
			return false;
		}
		return true;
	}

	// GetTextureInterface
	IUnknown * CDepthRenderTarget9::GetTextureInterface( void )
	{
		return NULL;
	}

	// GetRenderTargetInterface
	IUnknown * CDepthRenderTarget9::GetRenderTargetInterface( void )
	{
		return NULL;
	}

} // namespace xeres
